﻿#region License
// Copyright 2007-2008 Rory Plaire (codekaizen@gmail.com)
/*
 * This license governs use of the accompanying software. If you use the software, you
 * accept this license. If you do not accept the license, do not use the software.
 * 
 * 1. Definitions
 * The terms "reproduce," "reproduction," "derivative works," and "distribution" have the
 * same meaning here as under U.S. copyright law.
 * A "contribution" is the original software, or any additions or changes to the software.
 * A "contributor" is any person that distributes its contribution under this license.
 * "Licensed patents" are a contributor's patent claims that read directly on its contribution.
 * 
 * 2. Grant of Rights
 * (A) Copyright Grant- Subject to the terms of this license, including the license conditions 
 *     and limitations in section 3, each contributor grants you a non-exclusive, worldwide, 
 *     royalty-free copyright license to reproduce its contribution, prepare derivative works 
 *     of its contribution, and distribute its contribution or any derivative works that you create.
 * (B) Patent Grant- Subject to the terms of this license, including the license conditions and 
 *     limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free 
 *     license under its licensed patents to make, have made, use, sell, offer for sale, import, 
 *     and/or otherwise dispose of its contribution in the software or derivative works of the 
 *     contribution in the software.
 * 
 * 3. Conditions and Limitations
 * (A) No Trademark License- This license does not grant you rights to use any contributors' 
 *     name, logo, or trademarks.
 * (B) If you bring a patent claim against any contributor over patents that you claim are 
 *     infringed by the software, your patent license from such contributor to the software 
 *     ends automatically.
 * (C) If you distribute any portion of the software, you must retain all copyright, patent, 
 *     trademark, and attribution notices that are present in the software.
 * (D) If you distribute any portion of the software in source code form, you may do so only under 
 *     this license by including a complete copy of this license with your distribution. If you 
 *     distribute any portion of the software in compiled or object code form, you may only do so 
 *     under a license that complies with this license.
 * (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no 
 *     express warranties, guarantees or conditions. You may have additional consumer rights under 
 *     your local laws which this license cannot change. To the extent permitted under your local laws, 
 *     the contributors exclude the implied warranties of merchantability, fitness for a particular 
 *     purpose and non-infringement.
 * 
 */
#endregion

using System;
using System.Collections.Generic;
using System.Diagnostics;
using NPack.Interfaces;
using NPack.Matrix;
using Xunit;

namespace NPack.Tests
{
    public class ManagedVectorBufferTests
    {
        #region TestBufferedVector
        struct TestBufferedVector : IBufferedVector<DoubleComponent, TestBufferedVector>,
                                    IEquatable<TestBufferedVector>,
                                    IComparable<TestBufferedVector>,
                                    IComputable<Double, TestBufferedVector>
        {
            private readonly Int32 _index;
            private readonly Int32 _length;
            private readonly ManagedVectorBuffer<DoubleComponent, TestBufferedVector> _buffer;

            public TestBufferedVector(Int32 index, Int32 length, ManagedVectorBuffer<DoubleComponent, TestBufferedVector> buffer)
            {
                _index = index;
                _length = length;
                _buffer = buffer;
            }

            #region IBufferedVector<TestBufferedVector,DoubleComponent> Members

            public TestBufferedVector Clone()
            {
                throw new NotImplementedException();
            }

            public TestBufferedVector Negative()
            {
                throw new NotImplementedException();
            }

            public IVectorBuffer<DoubleComponent, TestBufferedVector> GetBuffer()
            {
                throw new NotImplementedException();
            }

            public Int32 Index
            {
                get { throw new NotImplementedException(); }
            }

            public Boolean ValueEquals(TestBufferedVector other)
            {
                if (other.ComponentCount != _length)
	            {
                    return false;
	            }

                for (Int32 i = 0; i < _length; i++)
                {
                    if (!this[i].Equals(other[i]))
                    {
                        return false;
                    }
                }

                return true;
            }

            #endregion

            #region IVector<DoubleComponent> Members

            public Int32 ComponentCount
            {
                get { return _length; }
            }

            public DoubleComponent[] Components
            {
                get
                {
                    Int32 count = ComponentCount;
                    DoubleComponent[] components = new DoubleComponent[count];

                    for (Int32 i = 0; i < count; i++)
                    {
                        components[i] = this[i];
                    }

                    return components;
                }
                set
                {
                    throw new NotImplementedException();
                }
            }

            public DoubleComponent this[Int32 index]
            {
                get
                {
                    return _buffer[_index, index];
                }
                set
                {
                    throw new NotImplementedException();
                }
            }

            public void GetComponents(out DoubleComponent a, out DoubleComponent b)
            {
                throw new System.NotImplementedException();
            }

            public void GetComponents(out DoubleComponent a, out DoubleComponent b, out DoubleComponent c)
            {
                throw new System.NotImplementedException();
            }

            public void GetComponents(out DoubleComponent a, out DoubleComponent b, out DoubleComponent c, out DoubleComponent d)
            {
                throw new System.NotImplementedException();
            }

            #endregion

            #region IMatrix<DoubleComponent> Members

            public Double Determinant
            {
                get { throw new NotImplementedException(); }
            }

            public Int32 ColumnCount
            {
                get { throw new NotImplementedException(); }
            }

            public MatrixFormat Format
            {
                get { throw new NotImplementedException(); }
            }

            public bool IsSingular
            {
                get { throw new NotImplementedException(); }
            }

            public bool IsInvertible
            {
                get { throw new NotImplementedException(); }
            }

            public IMatrix<DoubleComponent> Inverse
            {
                get { throw new NotImplementedException(); }
            }

            public bool IsSquare
            {
                get { throw new NotImplementedException(); }
            }

            public bool IsSymmetrical
            {
                get { throw new NotImplementedException(); }
            }

            public Int32 RowCount
            {
                get { throw new NotImplementedException(); }
            }

            public DoubleComponent this[Int32 row, Int32 column]
            {
                get
                {
                    throw new NotImplementedException();
                }
                set
                {
                    throw new NotImplementedException();
                }
            }

            /// <summary>
            /// Gets a row of the matrix
            /// </summary>
            /// <param name="row">The row index</param>
            /// <returns>The requested row</returns>
            public DoubleComponent[] GetRow(int row)
            {
                throw new NotImplementedException();
            }

            /// <summary>
            /// Gets a column of the matrix
            /// </summary>
            /// <param name="column">The column index</param>
            /// <returns>The requested column</returns>
            public DoubleComponent[] GetColumn(int column)
            {
                throw new NotImplementedException();
            }

            /// <summary>
            /// Returns the matrix as jagged array, <see cref="MatrixFormat.RowMajor"/>
            /// </summary>
            public DoubleComponent[][] GetAsJaggedArray()
            {
                throw new NotImplementedException();
            }

            /// <summary>
            /// Sets the matrix values from the provided <see cref="source"/>
            /// </summary>
            /// <remarks>The <paramref name="source"/> is interpreted as being <see cref="MatrixFormat.RowMajor"/></remarks>
            /// <exception cref="InvalidOperationException">
            /// Thrown if the format of <paramref name="source"/> does not match the matrix' size.
            /// </exception>
            public void SetFromJaggedArray(DoubleComponent[][] source)
            {
                throw new NotImplementedException();
            }

            IMatrix<DoubleComponent> IMatrix<DoubleComponent>.Clone()
            {
                throw new NotImplementedException();
            }

            public IMatrix<DoubleComponent> GetMatrix(Int32[] rowIndexes, Int32 startColumn, Int32 endColumn)
            {
                throw new NotImplementedException();
            }

            public IMatrix<DoubleComponent> Transpose()
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IEquatable<IMatrix<DoubleComponent>> Members

            public bool Equals(IMatrix<DoubleComponent> other)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IComparable<IMatrix<DoubleComponent>> Members

            public Int32 CompareTo(IMatrix<DoubleComponent> other)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IComputable<IMatrix<DoubleComponent>> Members

            public IMatrix<DoubleComponent> Abs()
            {
                throw new NotImplementedException();
            }

            public IMatrix<DoubleComponent> Set(Double value)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region ISubtractable<IMatrix<DoubleComponent>> Members

            public IMatrix<DoubleComponent> Subtract(IMatrix<DoubleComponent> b)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IHasZero<IMatrix<DoubleComponent>> Members

            public IMatrix<DoubleComponent> Zero
            {
                get { throw new NotImplementedException(); }
            }

            #endregion

            #region IAddable<IMatrix<DoubleComponent>> Members

            public IMatrix<DoubleComponent> Add(IMatrix<DoubleComponent> b)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IDivisible<IMatrix<DoubleComponent>> Members

            public IMatrix<DoubleComponent> Divide(IMatrix<DoubleComponent> b)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IHasOne<IMatrix<DoubleComponent>> Members

            public IMatrix<DoubleComponent> One
            {
                get { throw new NotImplementedException(); }
            }

            #endregion

            #region IMultipliable<IMatrix<DoubleComponent>> Members

            public IMatrix<DoubleComponent> Multiply(IMatrix<DoubleComponent> b)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IBooleanComparable<IMatrix<DoubleComponent>> Members

            public bool GreaterThan(IMatrix<DoubleComponent> value)
            {
                throw new NotImplementedException();
            }

            public bool GreaterThanOrEqualTo(IMatrix<DoubleComponent> value)
            {
                throw new NotImplementedException();
            }

            public bool LessThan(IMatrix<DoubleComponent> value)
            {
                throw new NotImplementedException();
            }

            public bool LessThanOrEqualTo(IMatrix<DoubleComponent> value)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IExponential<IMatrix<DoubleComponent>> Members

            public IMatrix<DoubleComponent> Power(Double exponent)
            {
                throw new NotImplementedException();
            }

            public IMatrix<DoubleComponent> Sqrt()
            {
                throw new NotImplementedException();
            }

            public IMatrix<DoubleComponent> Log(Double newBase)
            {
                throw new NotImplementedException();
            }

            public IMatrix<DoubleComponent> Log()
            {
                throw new NotImplementedException();
            }

            public IMatrix<DoubleComponent> Exp()
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IEnumerable<DoubleComponent> Members

            public IEnumerator<DoubleComponent> GetEnumerator()
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IEnumerable Members

            System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
            {
                throw new NotImplementedException();
            }

            #endregion
            /*
            #region IComputable<Double,IVector<DoubleComponent>> Members

            IVector<DoubleComponent> IComputable<Double, IVector<DoubleComponent>>.Set(Double value)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IComputable<IVector<DoubleComponent>> Members

            IVector<DoubleComponent> IComputable<IVector<DoubleComponent>>.Abs()
            {
                throw new NotImplementedException();
            }

            IVector<DoubleComponent> IComputable<IVector<DoubleComponent>>.Set(Double value)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region ISubtractable<IVector<DoubleComponent>> Members

            public IVector<DoubleComponent> Subtract(IVector<DoubleComponent> b)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IHasZero<IVector<DoubleComponent>> Members

            IVector<DoubleComponent> IHasZero<IVector<DoubleComponent>>.Zero
            {
                get { throw new NotImplementedException(); }
            }

            #endregion

            #region IAddable<IVector<DoubleComponent>> Members

            public IVector<DoubleComponent> Add(IVector<DoubleComponent> b)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IDivisible<IVector<DoubleComponent>> Members

            public IVector<DoubleComponent> Divide(IVector<DoubleComponent> b)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IHasOne<IVector<DoubleComponent>> Members

            IVector<DoubleComponent> IHasOne<IVector<DoubleComponent>>.One
            {
                get { throw new NotImplementedException(); }
            }

            #endregion

            #region IMultipliable<IVector<DoubleComponent>> Members

            public IVector<DoubleComponent> Multiply(IVector<DoubleComponent> b)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IBooleanComparable<IVector<DoubleComponent>> Members

            public bool GreaterThan(IVector<DoubleComponent> value)
            {
                throw new NotImplementedException();
            }

            public bool GreaterThanOrEqualTo(IVector<DoubleComponent> value)
            {
                throw new NotImplementedException();
            }

            public bool LessThan(IVector<DoubleComponent> value)
            {
                throw new NotImplementedException();
            }

            public bool LessThanOrEqualTo(IVector<DoubleComponent> value)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IExponential<IVector<DoubleComponent>> Members

            IVector<DoubleComponent> IExponential<IVector<DoubleComponent>>.Power(Double exponent)
            {
                throw new NotImplementedException();
            }

            IVector<DoubleComponent> IExponential<IVector<DoubleComponent>>.Sqrt()
            {
                throw new NotImplementedException();
            }

            IVector<DoubleComponent> IExponential<IVector<DoubleComponent>>.Log(Double newBase)
            {
                throw new NotImplementedException();
            }

            IVector<DoubleComponent> IExponential<IVector<DoubleComponent>>.Log()
            {
                throw new NotImplementedException();
            }

            IVector<DoubleComponent> IExponential<IVector<DoubleComponent>>.Exp()
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IMultipliable<Double,IVector<DoubleComponent>> Members

            public IVector<DoubleComponent> Multiply(Double b)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IDivisible<Double,IVector<DoubleComponent>> Members

            public IVector<DoubleComponent> Divide(Double b)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IEquatable<IVector<DoubleComponent>> Members

            public bool Equals(IVector<DoubleComponent> other)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IComparable<IVector<DoubleComponent>> Members

            public Int32 CompareTo(IVector<DoubleComponent> other)
            {
                throw new NotImplementedException();
            }

            #endregion
            */

            #region IEquatable<TestBufferedVector> Members

            public Boolean Equals(TestBufferedVector other)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IComparable<BufferedVector> Members

            public Int32 CompareTo(TestBufferedVector other)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IComputable<Double,BufferedVector> Members

            TestBufferedVector IComputable<Double, TestBufferedVector>.Set(Double value)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IComputable<BufferedVector> Members

            TestBufferedVector IComputable<TestBufferedVector>.Abs()
            {
                throw new NotImplementedException();
            }

            TestBufferedVector IComputable<TestBufferedVector>.Set(Double value)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region INegatable<BufferedVector> Members

            TestBufferedVector INegatable<TestBufferedVector>.Negative()
            {
                throw new NotImplementedException();
            }

            #endregion

            #region ISubtractable<BufferedVector> Members

            public TestBufferedVector Subtract(TestBufferedVector b)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IHasZero<BufferedVector> Members

            TestBufferedVector IHasZero<TestBufferedVector>.Zero
            {
                get { throw new NotImplementedException(); }
            }

            #endregion

            #region IAddable<BufferedVector> Members

            public TestBufferedVector Add(TestBufferedVector b)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IDivisible<BufferedVector> Members

            public TestBufferedVector Divide(TestBufferedVector b)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IHasOne<BufferedVector> Members

            TestBufferedVector IHasOne<TestBufferedVector>.One
            {
                get { throw new NotImplementedException(); }
            }

            #endregion

            #region IMultipliable<BufferedVector> Members

            public TestBufferedVector Multiply(TestBufferedVector b)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IBooleanComparable<BufferedVector> Members

            public bool GreaterThan(TestBufferedVector value)
            {
                throw new NotImplementedException();
            }

            public bool GreaterThanOrEqualTo(TestBufferedVector value)
            {
                throw new NotImplementedException();
            }

            public bool LessThan(TestBufferedVector value)
            {
                throw new NotImplementedException();
            }

            public bool LessThanOrEqualTo(TestBufferedVector value)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IExponential<BufferedVector> Members

            TestBufferedVector IExponential<TestBufferedVector>.Power(Double exponent)
            {
                throw new NotImplementedException();
            }

            TestBufferedVector IExponential<TestBufferedVector>.Sqrt()
            {
                throw new NotImplementedException();
            }

            TestBufferedVector IExponential<TestBufferedVector>.Log(Double newBase)
            {
                throw new NotImplementedException();
            }

            TestBufferedVector IExponential<TestBufferedVector>.Log()
            {
                throw new NotImplementedException();
            }

            TestBufferedVector IExponential<TestBufferedVector>.Exp()
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IMultipliable<Double,BufferedVector> Members

            TestBufferedVector IMultipliable<Double, TestBufferedVector>.Multiply(Double b)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IDivisible<Double,BufferedVector> Members

            TestBufferedVector IDivisible<Double, TestBufferedVector>.Divide(Double b)
            {
                throw new NotImplementedException();
            }

            #endregion
            
            //#region IAddable<Double,IVector<DoubleComponent>> Members

            //public IVector<DoubleComponent> Add(Double b)
            //{
            //    throw new NotImplementedException();
            //}

            //#endregion

            //#region ISubtractable<Double,IVector<DoubleComponent>> Members

            //public IVector<DoubleComponent> Subtract(Double b)
            //{
            //    throw new NotImplementedException();
            //}

            //#endregion

            #region IAddable<Double,TestBufferedVector> Members

            TestBufferedVector IAddable<Double, TestBufferedVector>.Add(Double b)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region ISubtractable<Double,TestBufferedVector> Members

            TestBufferedVector ISubtractable<Double, TestBufferedVector>.Subtract(Double b)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IEquatable<TestBufferedVector> Members

            bool IEquatable<TestBufferedVector>.Equals(TestBufferedVector other)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IVector<DoubleComponent,TestBufferedVector> Members


            public double Dot(TestBufferedVector vector)
            {
                throw new NotImplementedException();
            }

            public TestBufferedVector Cross(TestBufferedVector vector)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IComputable<double,IVector<DoubleComponent,TestBufferedVector>> Members

            IVector<DoubleComponent, TestBufferedVector> IComputable<double, IVector<DoubleComponent, TestBufferedVector>>.Set(double value)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IComputable<IVector<DoubleComponent,TestBufferedVector>> Members

            IVector<DoubleComponent, TestBufferedVector> IComputable<IVector<DoubleComponent, TestBufferedVector>>.Abs()
            {
                throw new NotImplementedException();
            }

            IVector<DoubleComponent, TestBufferedVector> IComputable<IVector<DoubleComponent, TestBufferedVector>>.Set(double value)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region INegatable<IVector<DoubleComponent,TestBufferedVector>> Members

            IVector<DoubleComponent, TestBufferedVector> INegatable<IVector<DoubleComponent, TestBufferedVector>>.Negative()
            {
                throw new NotImplementedException();
            }

            #endregion

            #region ISubtractable<IVector<DoubleComponent,TestBufferedVector>> Members

            public IVector<DoubleComponent, TestBufferedVector> Subtract(IVector<DoubleComponent, TestBufferedVector> b)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IHasZero<IVector<DoubleComponent,TestBufferedVector>> Members

            IVector<DoubleComponent, TestBufferedVector> IHasZero<IVector<DoubleComponent, TestBufferedVector>>.Zero
            {
                get { throw new NotImplementedException(); }
            }

            #endregion

            #region IAddable<IVector<DoubleComponent,TestBufferedVector>> Members

            public IVector<DoubleComponent, TestBufferedVector> Add(IVector<DoubleComponent, TestBufferedVector> b)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IDivisible<IVector<DoubleComponent,TestBufferedVector>> Members

            public IVector<DoubleComponent, TestBufferedVector> Divide(IVector<DoubleComponent, TestBufferedVector> b)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IHasOne<IVector<DoubleComponent,TestBufferedVector>> Members

            IVector<DoubleComponent, TestBufferedVector> IHasOne<IVector<DoubleComponent, TestBufferedVector>>.One
            {
                get { throw new NotImplementedException(); }
            }

            #endregion

            #region IMultipliable<IVector<DoubleComponent,TestBufferedVector>> Members

            public IVector<DoubleComponent, TestBufferedVector> Multiply(IVector<DoubleComponent, TestBufferedVector> b)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IBooleanComparable<IVector<DoubleComponent,TestBufferedVector>> Members

            public bool GreaterThan(IVector<DoubleComponent, TestBufferedVector> value)
            {
                throw new NotImplementedException();
            }

            public bool GreaterThanOrEqualTo(IVector<DoubleComponent, TestBufferedVector> value)
            {
                throw new NotImplementedException();
            }

            public bool LessThan(IVector<DoubleComponent, TestBufferedVector> value)
            {
                throw new NotImplementedException();
            }

            public bool LessThanOrEqualTo(IVector<DoubleComponent, TestBufferedVector> value)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IExponential<IVector<DoubleComponent,TestBufferedVector>> Members

            IVector<DoubleComponent, TestBufferedVector> IExponential<IVector<DoubleComponent, TestBufferedVector>>.Power(double exponent)
            {
                throw new NotImplementedException();
            }

            IVector<DoubleComponent, TestBufferedVector> IExponential<IVector<DoubleComponent, TestBufferedVector>>.Sqrt()
            {
                throw new NotImplementedException();
            }

            IVector<DoubleComponent, TestBufferedVector> IExponential<IVector<DoubleComponent, TestBufferedVector>>.Log(double newBase)
            {
                throw new NotImplementedException();
            }

            IVector<DoubleComponent, TestBufferedVector> IExponential<IVector<DoubleComponent, TestBufferedVector>>.Log()
            {
                throw new NotImplementedException();
            }

            IVector<DoubleComponent, TestBufferedVector> IExponential<IVector<DoubleComponent, TestBufferedVector>>.Exp()
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IAddable<double,IVector<DoubleComponent,TestBufferedVector>> Members

            IVector<DoubleComponent, TestBufferedVector> IAddable<double, IVector<DoubleComponent, TestBufferedVector>>.Add(double b)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region ISubtractable<double,IVector<DoubleComponent,TestBufferedVector>> Members

            IVector<DoubleComponent, TestBufferedVector> ISubtractable<double, IVector<DoubleComponent, TestBufferedVector>>.Subtract(double b)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IMultipliable<double,IVector<DoubleComponent,TestBufferedVector>> Members

            IVector<DoubleComponent, TestBufferedVector> IMultipliable<double, IVector<DoubleComponent, TestBufferedVector>>.Multiply(double b)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IDivisible<double,IVector<DoubleComponent,TestBufferedVector>> Members

            IVector<DoubleComponent, TestBufferedVector> IDivisible<double, IVector<DoubleComponent, TestBufferedVector>>.Divide(double b)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IEquatable<IVector<DoubleComponent,TestBufferedVector>> Members

            public bool Equals(IVector<DoubleComponent, TestBufferedVector> other)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IComparable<IVector<DoubleComponent,TestBufferedVector>> Members

            public int CompareTo(IVector<DoubleComponent, TestBufferedVector> other)
            {
                throw new NotImplementedException();
            }

            #endregion
        }
        #endregion

        #region TestBufferedVectorFactory
        class TestBufferedVectorFactory : IBufferedVectorFactory<DoubleComponent, TestBufferedVector>
        {
            #region IBufferedVectorFactory<TestBufferedVector,DoubleComponent> Members

            public TestBufferedVector CreateBufferedVector(IVectorBuffer<DoubleComponent, TestBufferedVector> vectorBuffer, Int32 index)
            {
                ManagedVectorBuffer<DoubleComponent, TestBufferedVector> buffer =
                    vectorBuffer as ManagedVectorBuffer<DoubleComponent, TestBufferedVector>;
                return new TestBufferedVector(index, buffer.GetVectorLength(index), buffer);
            }

            public TestBufferedVector CreateBufferedVector(IVectorBuffer<DoubleComponent, TestBufferedVector> vectorBuffer, int index, object context)
            {
                throw new System.NotImplementedException();
            }

            #endregion
        }
        #endregion

        [Fact]
        public void CreateManagedVectorBufferSucceeds()
        {
            ManagedVectorBuffer<DoubleComponent, TestBufferedVector> buffer =
                new ManagedVectorBuffer<DoubleComponent, TestBufferedVector>(new TestBufferedVectorFactory());

            Assert.NotNull(buffer);
        }

        [Fact]
        public void CreatingManagedVectorBufferWithNegativeMaximumCapacityFails()
        {
            Assert.Throws<ArgumentOutOfRangeException>(delegate()
                                {
                                    new ManagedVectorBuffer<DoubleComponent, TestBufferedVector>(
                                        new TestBufferedVectorFactory(), -1);
                                });
        }

        [Fact]
        public void CreatingManagedVectorBufferWithZeroMaximumCapacityFails()
        {
            Assert.Throws<ArgumentOutOfRangeException>(delegate()
                               {
                                   new ManagedVectorBuffer<DoubleComponent, TestBufferedVector>(
                                       new TestBufferedVectorFactory(), 0);
                               });
        }

        [Fact]
        public void AddingVectorsToManagedVectorBufferSucceeds1()
        {
            ManagedVectorBuffer<DoubleComponent, TestBufferedVector> buffer =
                new ManagedVectorBuffer<DoubleComponent, TestBufferedVector>(new TestBufferedVectorFactory());

            Random rnd = new MersenneTwister();

            const Int32 VectorCount = 60000;

            List<DoubleComponent> components = new List<DoubleComponent>(VectorCount * 3);

            DoubleComponent test = Double.NaN;
            for (Int32 i = 0; i < VectorCount; i++)
            {
                DoubleComponent x = rnd.NextDouble();
                DoubleComponent y = rnd.NextDouble();
                DoubleComponent w = rnd.NextDouble();
                TestBufferedVector vector = buffer.Add(x, y, w);
                Assert.Equal(x, vector[0]);
                Assert.Equal(y, vector[1]);
                Assert.Equal(w, vector[2]);
                //if (Double.IsNaN((Double)test)) test = x;
                //else if (!buffer[0, 0].Equals(test)) Debugger.Break();
                components.Add(x);
                components.Add(y);
                components.Add(w);
            }

            Assert.Equal(VectorCount, buffer.Count);

            List<TestBufferedVector> vectors = new List<TestBufferedVector>();

            foreach (TestBufferedVector vector in buffer)
            {
                vectors.Add(vector);
            }

            Assert.Equal(components.Count / 3, vectors.Count);

            Int32 componentIndex = 0;
            for (int i = 0; i < vectors.Count; i++)
            {
                Assert.Equal(components[componentIndex++], vectors[i][0]);
                Assert.Equal(components[componentIndex++], vectors[i][1]);
                Assert.Equal(components[componentIndex++], vectors[i][2]);
            }
        }

        [Fact]
        public void AddingVectorsToManagedVectorBufferSucceeds2()
        {
            ManagedVectorBuffer<DoubleComponent, TestBufferedVector> buffer =
                new ManagedVectorBuffer<DoubleComponent, TestBufferedVector>(new TestBufferedVectorFactory());

            TestBufferedVector vector;

            vector = buffer.Add(0, 1);
            Assert.Equal(0, (Double)vector[0]);
            Assert.Equal(1, (Double)vector[1]);

            vector = buffer.Add(10, 2);
            Assert.Equal(10, (Double)vector[0]);
            Assert.Equal(2, (Double)vector[1]);

            vector = buffer.Add(20, 3);
            Assert.Equal(20, (Double)vector[0]);
            Assert.Equal(3, (Double)vector[1]);

            vector = buffer.Add(30, 4);
            Assert.Equal(30, (Double)vector[0]);
            Assert.Equal(4, (Double)vector[1]);

            vector = buffer.Add(40, 5);
            Assert.Equal(40, (Double)vector[0]);
            Assert.Equal(5, (Double)vector[1]);

            Assert.Equal(5, buffer.Count);
        }

        [Fact]
        public void AddingAnIVectorToManagedVectorBufferSucceeds()
        {
            ManagedVectorBuffer<DoubleComponent, TestBufferedVector> buffer =
                new ManagedVectorBuffer<DoubleComponent, TestBufferedVector>(new TestBufferedVectorFactory());

            Vector<DoubleComponent> v = new Vector<DoubleComponent>(1.0, 2.0, 1.0);

            buffer.Add(v.Components);
        }

        [Fact]
        public void AddingATVectorToManagedVectorBufferSucceeds()
        {
            ManagedVectorBuffer<DoubleComponent, TestBufferedVector> buffer1 =
                new ManagedVectorBuffer<DoubleComponent, TestBufferedVector>(new TestBufferedVectorFactory());

            ManagedVectorBuffer<DoubleComponent, TestBufferedVector> buffer2 =
                new ManagedVectorBuffer<DoubleComponent, TestBufferedVector>(new TestBufferedVectorFactory());

            TestBufferedVector v1 = buffer1.Add(0, 1, 2);
            buffer2.Add(v1);

            TestBufferedVector v2 = buffer2[0];

            Assert.Equal(1, buffer2.Count);
            Assert.True(v1.ValueEquals(v2));
        }

        [Fact]
        public void SettingMaximumSizeLessThanCurrentSizeFails()
        {
            ManagedVectorBuffer<DoubleComponent, TestBufferedVector> buffer =
                new ManagedVectorBuffer<DoubleComponent, TestBufferedVector>(new TestBufferedVectorFactory());

            Assert.Throws<InvalidOperationException>(delegate() { buffer.MaximumSize = 128; });
        }

        [Fact]
        public void SettingMaximumSizeLessThanZeroFails()
        {
            ManagedVectorBuffer<DoubleComponent, TestBufferedVector> buffer =
                new ManagedVectorBuffer<DoubleComponent, TestBufferedVector>(new TestBufferedVectorFactory());

            Assert.Throws<ArgumentOutOfRangeException>(delegate() { buffer.MaximumSize = -1; });
        }

        [Fact]
        public void SettingMaximumSizeEqualToZeroFails()
        {
            ManagedVectorBuffer<DoubleComponent, TestBufferedVector> buffer =
                new ManagedVectorBuffer<DoubleComponent, TestBufferedVector>(new TestBufferedVectorFactory());

            Assert.Throws<ArgumentOutOfRangeException>(delegate() { buffer.MaximumSize = 0; });
        }

        [Fact]
        public void SettingMaximumSizeSucceeds()
        {
            ManagedVectorBuffer<DoubleComponent, TestBufferedVector> buffer =
                new ManagedVectorBuffer<DoubleComponent, TestBufferedVector>(new TestBufferedVectorFactory(), 64);

            Assert.Equal(64, buffer.MaximumSize);
            buffer.MaximumSize = 128;
            Assert.Equal(128, buffer.MaximumSize);
        }

        [Fact]
        public void TryingToExpandPastMaximumSizeFails()
        {
            ManagedVectorBuffer<DoubleComponent, TestBufferedVector> buffer =
                new ManagedVectorBuffer<DoubleComponent, TestBufferedVector>(new TestBufferedVectorFactory(), 128);
            Assert.Throws<InvalidOperationException>(delegate()
                                {
                                    for (Int32 i = 0; i <= buffer.MaximumSize + 1; i++)
                                    {
                                        buffer.Add(i, i);
                                    }
                                });
        }

        [Fact]
        public void TryingToAddVectorToBufferAtMaximumSizeFails()
        {
            ManagedVectorBuffer<DoubleComponent, TestBufferedVector> buffer =
                new ManagedVectorBuffer<DoubleComponent, TestBufferedVector>(new TestBufferedVectorFactory(), 100);
            Assert.Throws<InvalidOperationException>(delegate()
                                {
                                    for (Int32 i = 0; i <= buffer.MaximumSize + 1; i++)
                                    {
                                        buffer.Add(i, i);
                                    }
                                });
        }

        [Fact]
        public void FillingTheBufferToMaximumSizeStartingAtInitialSizeSucceeds()
        {
            ManagedVectorBuffer<DoubleComponent, TestBufferedVector> buffer =
                new ManagedVectorBuffer<DoubleComponent, TestBufferedVector>(new TestBufferedVectorFactory(), 100);

            for (Int32 i = 0; i < buffer.MaximumSize; i++)
            {
                buffer.Add(i, i);
            }
        }

        [Fact]
        public void RemovingVectorsFromManagedBufferSucceeds()
        {
            ManagedVectorBuffer<DoubleComponent, TestBufferedVector> buffer =
                new ManagedVectorBuffer<DoubleComponent, TestBufferedVector>(new TestBufferedVectorFactory());

            Random rnd = new MersenneTwister();

            const Int32 VectorCount = 24000;

            for (Int32 i = 0; i < VectorCount; i++)
            {
                DoubleComponent x = rnd.NextDouble();
                DoubleComponent y = rnd.NextDouble();
                DoubleComponent z = rnd.NextDouble();
                DoubleComponent w = rnd.NextDouble();
                buffer.Add(x, y, z, w);
            }

            for (Int32 i = 0; i < VectorCount; i++)
            {
                buffer.Remove(i);
                Assert.Equal(VectorCount - (i + 1), buffer.Count);
            }
        }

        [Fact]
        public void RemovingAndAddingVectorsFromBufferKeepsSize1()
        {
            ManagedVectorBuffer<DoubleComponent, TestBufferedVector> buffer =
                new ManagedVectorBuffer<DoubleComponent, TestBufferedVector>(new TestBufferedVectorFactory());

            Random rnd = new MersenneTwister();

            const Int32 VectorCount = 24000;

            for (Int32 i = 0; i < VectorCount; i++)
            {
                DoubleComponent x = rnd.NextDouble();
                DoubleComponent y = rnd.NextDouble();
                DoubleComponent z = rnd.NextDouble();
                DoubleComponent w = rnd.NextDouble();
                buffer.Add(x, y, z, w);
            }

            for (Int32 i = 0; i < VectorCount; i++)
            {
                buffer.Remove(i);
            }

            for (Int32 i = 0; i < VectorCount; i++)
            {
                DoubleComponent x = rnd.NextDouble();
                DoubleComponent y = rnd.NextDouble();
                DoubleComponent z = rnd.NextDouble();
                DoubleComponent w = rnd.NextDouble();
                buffer.Add(x, y, z, w);
            }

            Assert.Equal(VectorCount, buffer.Count);
        }

        [Fact]
        public void RemovingAndAddingVectorsFromBufferKeepsSize2()
        {
            ManagedVectorBuffer<DoubleComponent, TestBufferedVector> buffer =
                new ManagedVectorBuffer<DoubleComponent, TestBufferedVector>(new TestBufferedVectorFactory());

            Random rnd = new MersenneTwister();

            const Int32 VectorCount = 24000;

            for (Int32 i = 0; i < VectorCount; i++)
            {
                DoubleComponent x = rnd.NextDouble();
                DoubleComponent y = rnd.NextDouble();
                DoubleComponent z = rnd.NextDouble();
                buffer.Add(x, y, z);
            }

            for (Int32 i = 0; i < VectorCount; i++)
            {
                buffer.Remove(i);
            }

            for (Int32 i = 0; i < VectorCount; i++)
            {
                DoubleComponent x = rnd.NextDouble();
                DoubleComponent y = rnd.NextDouble();
                DoubleComponent z = rnd.NextDouble();
                buffer.Add(x, y, z);
            }

            Assert.Equal(VectorCount, buffer.Count);
        }

        [Fact]
        public void CountIsCorrect()
        {
            ManagedVectorBuffer<DoubleComponent, TestBufferedVector> buffer =
                new ManagedVectorBuffer<DoubleComponent, TestBufferedVector>(new TestBufferedVectorFactory());

            Random rnd = new MersenneTwister();

            const Int32 VectorCount = 12000;

            for (Int32 i = 0; i < VectorCount; i++)
            {
                DoubleComponent x = rnd.NextDouble();
                DoubleComponent y = rnd.NextDouble();
                DoubleComponent z = rnd.NextDouble();
                DoubleComponent w = rnd.NextDouble();
                buffer.Add(x, y, z, w);
                Assert.Equal(i + 1, buffer.Count);
            }
        }

        [Fact]
        public void ContainsTVectorIsNotImplemented()
        {
            ManagedVectorBuffer<DoubleComponent, TestBufferedVector> buffer =
                new ManagedVectorBuffer<DoubleComponent, TestBufferedVector>(new TestBufferedVectorFactory());

            TestBufferedVector v = new TestBufferedVector();
            Assert.Throws<NotImplementedException>(delegate() { buffer.Contains(v); });
        }

        //[Fact]
        //public void ContainsIVectorIsNotImplemented()
        //{
        //    ManagedVectorBuffer<DoubleComponent, TestBufferedVector> buffer =
        //        new ManagedVectorBuffer<DoubleComponent, TestBufferedVector>(new TestBufferedVectorFactory());

        //    Vector<DoubleComponent> v = new Vector<DoubleComponent>();
        //    Assert.Throws<NotImplementedException>(delegate() { buffer.Contains(v); });
        //}

        [Fact]
        public void ItemIndexerOutOfRangeFails1()
        {
            ManagedVectorBuffer<DoubleComponent, TestBufferedVector> buffer =
                new ManagedVectorBuffer<DoubleComponent, TestBufferedVector>(new TestBufferedVectorFactory());

            Assert.Throws<ArgumentOutOfRangeException>(delegate() { TestBufferedVector vector = buffer[-1]; });
        }

        [Fact]
        public void ItemIndexerOutOfRangeFails2()
        {
            ManagedVectorBuffer<DoubleComponent, TestBufferedVector> buffer =
                new ManagedVectorBuffer<DoubleComponent, TestBufferedVector>(new TestBufferedVectorFactory());

            Assert.Throws<ArgumentOutOfRangeException>(delegate() { TestBufferedVector vector = buffer[0]; });
        }

        [Fact]
        public void ComponentIndexerOutOfRangeFails1()
        {
            ManagedVectorBuffer<DoubleComponent, TestBufferedVector> buffer =
                new ManagedVectorBuffer<DoubleComponent, TestBufferedVector>(new TestBufferedVectorFactory());

            buffer.Add(0, 1, 2);

            Assert.Throws<ArgumentOutOfRangeException>(delegate() { DoubleComponent component = buffer[0, -1]; });
        }

        [Fact]
        public void ComponentIndexerOutOfRangeFails2()
        {
            ManagedVectorBuffer<DoubleComponent, TestBufferedVector> buffer =
                new ManagedVectorBuffer<DoubleComponent, TestBufferedVector>(new TestBufferedVectorFactory());

            buffer.Add(0, 1, 2);

            Assert.Throws<ArgumentOutOfRangeException>(delegate() { DoubleComponent component = buffer[0, 3]; });
        }

        [Fact]
        public void ComponentIndexerOutOfRangeFails3()
        {
            ManagedVectorBuffer<DoubleComponent, TestBufferedVector> buffer =
                new ManagedVectorBuffer<DoubleComponent, TestBufferedVector>(new TestBufferedVectorFactory());

            buffer.Add(0, 1, 2);

            Assert.Throws<ArgumentOutOfRangeException>(delegate() { DoubleComponent component = buffer[-1, 0]; });
        }

        [Fact]
        public void ComponentIndexerOutOfRangeFails4()
        {
            ManagedVectorBuffer<DoubleComponent, TestBufferedVector> buffer =
                new ManagedVectorBuffer<DoubleComponent, TestBufferedVector>(new TestBufferedVectorFactory());

            buffer.Add(0, 1, 2);

            Assert.Throws<ArgumentOutOfRangeException>(delegate() { DoubleComponent component = buffer[1, 0]; });
        }

        [Fact]
        public void ClearingTheBufferSucceeds()
        {
            ManagedVectorBuffer<DoubleComponent, TestBufferedVector> buffer =
                new ManagedVectorBuffer<DoubleComponent, TestBufferedVector>(new TestBufferedVectorFactory(), 100);

            Random rnd = new MersenneTwister();

            const Int32 VectorCount = 100;

            for (Int32 i = 0; i < VectorCount; i++)
            {
                DoubleComponent x = rnd.NextDouble();
                DoubleComponent y = rnd.NextDouble();
                DoubleComponent w = rnd.NextDouble();
                buffer.Add(x, y, w);
            }

            Assert.Equal(VectorCount, buffer.Count);
            buffer.Clear();
            Assert.Equal(0, buffer.Count);
        }
    }
}
